from django.http import JsonResponse
from django.views.generic import View
from django.http import HttpResponseRedirect

from APKManager.apps import ApkmanagerConfig
from .helper import *
from Common.utils import get_request_parameters
from .errcode import *


def json_response(errcode, object=None):
    data = {"rltcode": errcode.errcode,
            "rltmsg": errcode.errmsg,
            "object": object}
    return JsonResponse(data)


def login_required(**kwargs):
    redirect_url = kwargs.get('redirect_url')

    def login_check(proc):
        def wraped(request, *args, **kwargs2):
            reqobj = None
            if isinstance(request, View):
                reqobj = request.request
            elif isinstance(request, HttpRequest):
                reqobj = request
            else:
                raise errInvalidRequest

            uid = reqobj.session.get('id')
            if not uid:
                if not redirect_url:
                    return json_response(errLoginRequired)
                else:
                    return HttpResponseRedirect(redirect_url)

            reqobj.session.user = model_find(WbUser, id=uid)

            return proc(request, *args, **kwargs2)

        return wraped

    return login_check


def permissions_required(**kwargs):
    perms = kwargs.get('permissions')
    redirect_url = kwargs.get('redirect_url')

    def check_perms(proc):
        @login_required(**kwargs)
        def wraped(request, *args, **kwargs2):
            user = request.session.user
            if not perms:
                return proc(request, *args, **kwargs2)

            for p in user.group.permissions:
                if p.code in perms:
                    return proc(request, *args, **kwargs2)

            if not redirect_url:
                return HttpResponseRedirect(redirect_url)
            else:
                return json_response(errPermissionDenied)

        return wraped

    return check_perms


class API(object):
    @staticmethod
    def login(request, *args, **kwargs):
        try:
            code, username, password = get_request_parameters(request.POST,
                                                              'validation_code',
                                                              'username',
                                                              'password')
            if not request.session.has_key('validation_code'):
                raise errInvalidRequest

            if code != request.session['validation_code']:
                raise errInvalidValidationCode

            user = Helper.authenticate(username, password)
            request.session['id'] = user.id
            request.session.set_expiry(0)
            return json_response(errOK)

        except GBErr as e:
            return json_response(e)

    @staticmethod
    def logout(request, *args, **kwargs):
        if request.session.has_key('id'):
            del request.session['id']
        return json_response(errOK)

    @staticmethod
    @login_required()
    def update_password(request, *args, **kwargs):
        try:
            username, old_password, new_password = get_request_parameters(request,
                                                                          "username",
                                                                          "old_password",
                                                                          "new_password")
            if request.session.user.password != hashlib.md5(old_password).hexdigest():
                raise errInvalidUserNameOrPassword

            model_set(request.session.user, password=hashlib.md5(new_password).hexdigest())

            return json_response(errOK)

        except GBErr as e:
            return json_response(e)

    @staticmethod
    @permissions_required(permissions=[8000])
    def save_supplier_info(request, *args, **kwargs):
        try:
            supplier = Helper.save_supplier(request.session.user, **request.POST)
            model_set(supplier, status=status_model.get('Normal'))
            return json_response(errOK)
        except GBErr as e:
            return json_response(e)

    @staticmethod
    @permissions_required(permissions=[])
    def submit_supplier_info(request, *args, **kwargs):
        try:
            supplier = Helper.save_supplier(request.session.user, **request.POST)
            model_set(supplier, status=status_model.get_item('Submitted'))
            return json_response(errOK)
        except GBErr as e:
            return json_response(e)

    @staticmethod
    @permissions_required(permissions=[])
    def reject_supplier_info(request, *args, **kwargs):
        files = request.FILES.getlist('attachment')
        item = request.POST.get('item')
        description = request.POST.get('description')
        id = request.POST.get('id')

        try:
            supplier = model_find(WbSupplier, id=id)
            if not supplier:
                raise errSupplierNotFound

            if not supplier.status.name == "Auditing":
                raise errSupplierNoSubmitted

            path = Helper.upload_file(request.session.user, files)
            audit_record = model_create(WbGameAuditRecord, item=item, description=description, attachment=path[0])
            audit = model_create(WbAudit,
                                 auditor=request.session.user,
                                 status=status_model.get_item('Rejected'))
            audit.audits.append(audit_record)
            return json_response(errOK)
        except GBErr as e:
            return json_response(e)

    @staticmethod
    @permissions_required(permissions=[])
    def accept_supplier_info(request, *args, **kwargs):
        files = request.FILES.getlist('attachment')
        item = request.POST.get('item')
        description = request.POST.get('description')
        id = request.POST.get('id')

        try:
            supplier = model_find(WbSupplier, id=id)
            if not supplier:
                raise errSupplierNotFound

            if not supplier.status.name == "Auditing":
                raise errSupplierNoSubmitted

            path = Helper.upload_file(request.session.user, files)
            audit_record = model_create(WbGameAuditRecord,
                                        item=item,
                                        description=description,
                                        attachment=path[0])
            audit = model_create(WbAudit,
                                 auditor=request.session.user,
                                 status=status_model.get_item('Done'))
            audit.audits.append(audit_record)
            return json_response(errOK)
        except GBErr as e:
            return json_response(e)

    @staticmethod
    @permissions_required(permissions=[])
    def query_suppliers(request, *args, **kwargs):
        orderby = None
        offset = int(request.POST.get('iDisplayStart'))
        max_num = int(request.POST.get('iDisplayLength'))
        status = int(request.POST.get('status', Status.kInAuditing))
        total = WbCpInfo.get_total(status=status)

        resp_data = {
            'sEcho': request.POST.get('sEcho'),
            'iTotalRecords': max_num,
            'iTotalDisplayRecords': total,
            'aaData': []
        }
        for p in WbCpInfo.query(max_num, offset, orderby, False, status=status):
            resp_data['aaData'].append({'index': 0,
                                        'company': p.company,
                                        'name': p.account.account,
                                        'id': p.id,
                                        'ctime': p.ctime})
        return JsonResponse(resp_data)
        pass

